#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

//定义栈里面元素的类型
typedef int ElementType;

//定义顺序栈的结构
typedef struct  {
    ElementType *data; //指向存储元素的数组
    int top; //记录栈顶的位置
    int capacity; //记录栈的最大容量
}SepStack;

// 打印栈元素（从栈底到栈顶）
void printStack(SepStack *s) {
    if (s == NULL || s->data == NULL) {
        printf("参数不合法或栈未初始化\n");
        return;
    }
    if (s->top == -1) {
        printf("栈为空\n");
        return;
    }
    printf("栈元素（顶->底）：");
    for (int i = s->top; i >= 0; i--) {  // 从索引0遍历到top
        printf("%d ", s->data[i]);
    }
    printf("\n");
}

//初始化
void initStack(SepStack *s) {
    //1.判断参数是否合法
    if(s==NULL) {
        printf("指针参数为空，初始化失败");
        return;
    }

    //2.为数组分配内存空间
    s->data=(ElementType*)malloc(sizeof(ElementType));
    if(s->data==NULL) {
        printf("初始化内存空间分配失败");
        return;
    }
    s->top=-1; //top表示栈顶元素位置
    s->capacity=4; //给栈一个空间容量
    printf("finish\n");
}


//入栈
void push(SepStack *s, ElementType e) {
    if (s == NULL || s->data == NULL) {
        printf("参数不合法或栈未初始化\n");
        return;
    }

    //检查是否满栈
    if(s->top==s->capacity-1) {
        //扩容空间
        ElementType *temp = (ElementType*)realloc(s->data, s->capacity * 2);
        if(temp==NULL) {
            printf("扩容失败");
            return;
          }
          s->capacity *=2;
          s->data=temp; // 更新栈底层的数组指针
          printf("栈已扩容，新容量：%d\n", s->capacity);
    }
    // 先移动栈顶指针，再赋值（避免越界）
    s->top++;
    s->data[s->top] = e;
    printf("入栈成功：%d\n", e);
}

//判断是否为空
bool isEmpty(SepStack *s) {
    return s->top == -1;
}

//判断是否满栈
bool isFull(SepStack *s) {
    return s->top == s->capacity - 1;
}

//计算栈的长度
int length(SepStack *s) {
    return s->top + 1;
}

//判断出栈
void pop(SepStack *s) {
    s->top--;
}

//获取栈顶元素
ElementType topValue(SepStack *s) {
    return s->data[s->top];
}

int main() {
    // 设置控制台为UTF-8编码
    #ifdef _WIN32
    system("chcp 65001 > null");
    #endif

    //初始化
    SepStack s;
    initStack(&s);

    //入栈
    push(&s,10);
    printf("栈的长度是：%d \n\n",length(&s));
    push(&s,20);
    printf("栈的长度是：%d \n\n",length(&s));

    //打印栈顶元素
    printf("栈顶元素是：%d\n",topValue(&s));
    //打印栈的全部元素
    printStack(&s);

    return 0;
}